package com.education.platform.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.education.platform.common.ResultCode;
import com.education.platform.dto.article.ArticleCreateDTO;
import com.education.platform.entity.Article;
import com.education.platform.exception.BusinessException;
import com.education.platform.mapper.ArticleMapper;
import com.education.platform.service.ArticleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文章服务实现类
 *
 * @author education-platform
 * @since 2024-09-27
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ArticleServiceImpl implements ArticleService {

    private final ArticleMapper articleMapper;

    @Override
    @Transactional
    public Long createArticle(ArticleCreateDTO articleCreateDTO) {
        Article article = new Article();
        BeanUtil.copyProperties(articleCreateDTO, article);
        
        // 设置作者ID
        Long userId = StpUtil.getLoginIdAsLong();
        article.setAuthorId(userId);
        
        // 设置默认状态
        if (article.getStatus() == null) {
            article.setStatus(Article.Status.DRAFT.name());
        }
        
        // 设置初始统计值
        article.setViewCount(0);
        article.setLikeCount(0);
        
        articleMapper.insert(article);
        log.info("创建文章成功, ID: {}, 作者: {}", article.getId(), userId);
        return article.getId();
    }

    @Override
    @Transactional
    public void updateArticle(Long id, ArticleCreateDTO articleCreateDTO) {
        Article article = getArticleById(id);
        
        // 检查权限：只有作者本人或管理员可以修改
        Long userId = StpUtil.getLoginIdAsLong();
        if (!article.getAuthorId().equals(userId) && !StpUtil.hasRole("ADMIN")) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        BeanUtil.copyProperties(articleCreateDTO, article, "id", "authorId", "viewCount", "likeCount", "createdAt");
        articleMapper.updateById(article);
        log.info("更新文章成功, ID: {}", id);
    }

    @Override
    @Transactional
    public void deleteArticle(Long id) {
        Article article = getArticleById(id);
        
        // 检查权限
        Long userId = StpUtil.getLoginIdAsLong();
        if (!article.getAuthorId().equals(userId) && !StpUtil.hasRole("ADMIN")) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        articleMapper.deleteById(id);
        log.info("删除文章成功, ID: {}", id);
    }

    @Override
    public Article getArticleById(Long id) {
        Article article = articleMapper.selectById(id);
        if (article == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }
        return article;
    }

    @Override
    public IPage<Article> getArticlePage(Page<Article> page, String status, String keyword, String tags) {
        return articleMapper.selectArticlePageWithAuthor(page, status, keyword, tags);
    }

    @Override
    public List<Article> getMyArticles(Long authorId) {
        return articleMapper.selectByAuthorId(authorId);
    }

    @Override
    @Transactional
    public void publishArticle(Long id) {
        Article article = getArticleById(id);
        
        // 检查权限
        Long userId = StpUtil.getLoginIdAsLong();
        if (!article.getAuthorId().equals(userId) && !StpUtil.hasRole("ADMIN")) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        article.setStatus(Article.Status.PUBLISHED.name());
        article.setPublishedAt(LocalDateTime.now());
        articleMapper.updateById(article);
        log.info("发布文章成功, ID: {}", id);
    }

    @Override
    @Transactional
    public void archiveArticle(Long id) {
        Article article = getArticleById(id);
        
        // 检查权限
        Long userId = StpUtil.getLoginIdAsLong();
        if (!article.getAuthorId().equals(userId) && !StpUtil.hasRole("ADMIN")) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        
        article.setStatus(Article.Status.ARCHIVED.name());
        articleMapper.updateById(article);
        log.info("归档文章成功, ID: {}", id);
    }

    @Override
    @Transactional
    public void incrementViewCount(Long id) {
        articleMapper.incrementViewCount(id);
    }

    @Override
    @Transactional
    public void incrementLikeCount(Long id) {
        articleMapper.incrementLikeCount(id);
    }

    @Override
    public List<Article> getHotArticles(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        return articleMapper.selectHotArticles(limit);
    }

    @Override
    public List<Article> getArticlesByTag(String tag) {
        return articleMapper.selectByTag(tag);
    }
}

